home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / gemfsc20 / gemfsc20.lzh / GEMFUNCS / FRMDIAL.C < prev    next >
C/C++ Source or Header  |  1993-03-20  |  11KB  |  442 lines

  1. /**************************************************************************
  2.  *
  3.  *************************************************************************/
  4.  
  5. #include "gemfintl.h"
  6.  
  7. /*----------------------------------------------------------------------------
  8.  *
  9.  *--------------------------------------------------------------------------*/
  10.  
  11. static XUBT_STATUS maybe_touch_object  __PROTO((OBJECT *ptree, short obj));
  12. static short       call_system_form_do __PROTO((FormControl *ctl));
  13. static short       find_mover_object   __PROTO((OBJECT *ptree));
  14.  
  15. /*-------------------------------------------------------------------------
  16.  *
  17.  *-----------------------------------------------------------------------*/
  18.  
  19. #define NO_FLAGS        (-1)
  20. #define BLITOPTIONS     (FRM_USEBLIT|FRM_MOVEABLE)
  21. #define CTL_ALLOCATED    0x80000000L
  22.  
  23. long  _FrmDefaults    = FRM_NORMAL;
  24.  
  25. long         (*_FrBltVector) __PROTO((short options, void *buffer, void *rect));
  26. static short (*default_form_do) __PROTO((FormControl *ctl)) = call_system_form_do;
  27.  
  28. /*-------------------------------------------------------------------------
  29.  *
  30.  *-----------------------------------------------------------------------*/
  31.  
  32. static short call_system_form_do(ctl)
  33.     register FormControl *ctl;
  34. {
  35.     return form_do(ctl->ptree, ctl->editobj);
  36. }
  37.  
  38.  
  39. /*-------------------------------------------------------------------------
  40.  *
  41.  *-----------------------------------------------------------------------*/
  42.  
  43. static XUBT_STATUS maybe_touch_object(ptree, obj)
  44.     OBJECT *ptree;
  45.     short    obj;
  46. {
  47.     OBJECT        *pobj;
  48.     XUSERBLK    *xub;
  49.     short         clicks;
  50.     short         mx;
  51.     short         my;
  52.     short         dmy;
  53.  
  54.     clicks = (obj & 0x8000) ? 2 : 1;
  55.     obj &= 0x7FFF;
  56.     pobj = &ptree[obj];
  57.  
  58.     if (pobj->ob_flags & INDIRECT) {
  59.         xub = *(XUSERBLK **)pobj->ob_spec;
  60.     } else {
  61.         xub = (XUSERBLK *)pobj->ob_spec;
  62.     }
  63.  
  64.     if ((pobj->ob_type & 0x00FF) == G_USERDEF &&
  65.             (xub->ub_self == xub) &&
  66.             (xub->ub_touch != NULL)) {
  67.         graf_mkstate(&mx, &my, &dmy, &dmy);
  68.         return (*xub->ub_touch)(xub, mx, my, clicks);
  69.     }
  70.  
  71.     return XUBT_NONE;
  72.  
  73. }
  74.  
  75. /*-------------------------------------------------------------------------
  76.  *
  77.  *-----------------------------------------------------------------------*/
  78.  
  79. static short find_mover_object(ptree)
  80.     register OBJECT *ptree;
  81. {
  82.     register OBJECT *pobj      = ptree;
  83.     register short       obj        = 0;
  84.     register short       ob_flags;
  85.  
  86.     for (;;) {
  87.         ob_flags = pobj->ob_flags;
  88.         if (ob_flags & FRM_MOVER) {
  89.             return obj;
  90.         }
  91.         if (ob_flags & LASTOB) {
  92.             return NO_OBJECT;
  93.         }
  94.         ++obj;
  95.         ++pobj;
  96.     }
  97. }
  98.  
  99. /*-------------------------------------------------------------------------
  100.  *
  101.  *-----------------------------------------------------------------------*/
  102.  
  103. FormControl *_FrmSetup(ctl, options, ptree, pboundrect)
  104.     register FormControl *ctl;
  105.     register long         options;
  106.     register OBJECT      *ptree;
  107.     register GRECT         *pboundrect;
  108. {
  109.     if (pboundrect == NULL) {
  110.         pboundrect = &gl_rwdesk;
  111.     }
  112.  
  113.     if (!(options & FRM_NODEFAULTS)) {
  114.         options |= _FrmDefaults;
  115.     }
  116.  
  117.     ctl->ptree          = ptree;
  118.     ctl->pboundrect   = pboundrect;
  119.     ctl->options      = options & FRM_OPTIONBITS;
  120.     ctl->form_do      = default_form_do;
  121.     ctl->editobj      = ROOT;
  122.     ctl->parentobj      = ROOT;
  123.     ctl->moverobj      = NO_OBJECT;
  124.     ctl->treeflags      = NO_FLAGS;
  125.     ctl->select_state = SELECTED;
  126.     ctl->blitbuffer   = NULL;
  127.  
  128.     if (options & FRM_DSTART) {
  129.         if (options & FRM_NEARMOUSE) {
  130.             short mx, my, dmy;
  131.             graf_mkstate(&mx, &my, &dmy, &dmy);
  132.             ptree->ob_x = mx - (ptree->ob_width  / 2);
  133.             ptree->ob_y = my - (ptree->ob_height / 2);
  134.             frm_confine(ptree, pboundrect);
  135.         } else if (options & FRM_CENTER) {
  136.             frmx_center(ptree, &ctl->scrnrect);
  137.         }
  138.     }
  139.  
  140.     frm_sizes(ptree, &ctl->scrnrect);
  141.     rc_scale(&ctl->scrnrect, &ctl->littlerect, 20);
  142.  
  143.     if (options & FRM_DSTART) {
  144.         if ((options & BLITOPTIONS) && _FrBltVector != NULL) {
  145.             long blitbytes;
  146.             blitbytes = (*_FrBltVector)(GRF_BMEMCALC, NULL, &ctl->scrnrect);
  147.             if (NULL != (ctl->blitbuffer = apl_malloc(blitbytes))) {
  148.                 ctl->moverobj = find_mover_object(ptree);
  149.                 if (ctl->moverobj == NO_OBJECT && (options & FRM_MOVEABLE)) {
  150.                     ctl->moverobj  = ROOT;
  151.                     ctl->treeflags = frm_mkmoveable(ptree, ROOT);
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     return ctl;
  158. }
  159.  
  160. /*-------------------------------------------------------------------------
  161.  *
  162.  *-----------------------------------------------------------------------*/
  163.  
  164. void frm_cleanup(ctl)
  165.     register FormControl *ctl;
  166. {
  167.     if (ctl != NULL) {
  168.         if (ctl->blitbuffer != NULL) {
  169.             apl_free(ctl->blitbuffer);
  170.         }
  171.         if (ctl->ptree != NULL && ctl->treeflags != NO_FLAGS) {
  172.             ctl->ptree->ob_flags = ctl->treeflags;
  173.         }
  174.         if (ctl->options & CTL_ALLOCATED) {
  175.             apl_free(ctl);
  176.         }
  177.     }
  178. }
  179.  
  180. /*-------------------------------------------------------------------------
  181.  *
  182.  *-----------------------------------------------------------------------*/
  183.  
  184. FormControl *frm_init(options, ptree, pboundrect)
  185.     long        options;
  186.     OBJECT        *ptree;
  187.     GRECT        *pboundrect;
  188. {
  189.     FormControl *ctl;
  190.  
  191.     if (NULL == (ctl = apl_malloc((long)sizeof(FormControl)))) {
  192.         return NULL;
  193.     } else {
  194.         _FrmSetup(ctl, options|FRM_DSTART, ptree, pboundrect);
  195.         ctl->options |= CTL_ALLOCATED;
  196.         return ctl;
  197.     }
  198. }
  199.  
  200. /*-------------------------------------------------------------------------
  201.  *
  202.  *-----------------------------------------------------------------------*/
  203.  
  204. void frm_start(ctl)
  205.     register FormControl *ctl;
  206. {
  207.     if (ctl->blitbuffer != NULL) {
  208.         (*_FrBltVector)(GRF_BFROMSCREEN, ctl->blitbuffer, &ctl->scrnrect);
  209.     }
  210.  
  211.     frmx_dial(FMD_START, &ctl->littlerect, &ctl->scrnrect);
  212.  
  213.     if (ctl->options & FRM_EXPLODE) {
  214.         frmx_dial(FMD_GROW,  &ctl->littlerect, &ctl->scrnrect);
  215.     }
  216.  
  217. }
  218.  
  219. /*-------------------------------------------------------------------------
  220.  *
  221.  *-----------------------------------------------------------------------*/
  222.  
  223. void frm_draw(ctl, obj)
  224.     register FormControl *ctl;
  225.     short                   obj;
  226. {
  227.     objc_draw(ctl->ptree, obj, MAX_DEPTH, RECTVALS(ctl->pboundrect));
  228. }
  229.  
  230. /*-------------------------------------------------------------------------
  231.  *
  232.  *-----------------------------------------------------------------------*/
  233.  
  234. void frm_finish(ctl)
  235.     register FormControl *ctl;
  236. {
  237.     if (ctl->options & FRM_EXPLODE) {
  238.         frmx_dial(FMD_SHRINK, &ctl->littlerect, &ctl->scrnrect);
  239.     }
  240.  
  241.     if (ctl->blitbuffer != NULL) {
  242.         (*_FrBltVector)(GRF_BTOSCREEN, ctl->blitbuffer, &ctl->scrnrect);
  243.     } else {
  244.         frmx_dial(FMD_FINISH, &ctl->littlerect, &ctl->scrnrect);
  245.         evnx_timer(1L);
  246.     }
  247.  
  248. }
  249.  
  250. /*-------------------------------------------------------------------------
  251.  *
  252.  *-----------------------------------------------------------------------*/
  253.  
  254. void frm_move(ctl)
  255.     register FormControl *ctl;
  256. {
  257.     short             oldmouse;
  258.     short             mb;
  259.     short             dmy;
  260.     register short     adjust;
  261.     register GRECT *prect = (GRECT *)&ctl->ptree->ob_x;
  262.  
  263.     if (ctl->blitbuffer == NULL) {
  264.         return;
  265.     }
  266.  
  267.     /*
  268.      * delay very briefly, then see if the mouse button is still down.
  269.      * if it's not, just return.  this prevents false 'moves' when all
  270.      * the user did was miss the button s/he was after.
  271.      */
  272.  
  273.     evnx_timer(75L);
  274.     graf_mkstate(&dmy, &dmy, &mb, &dmy);
  275.     if (!mb) {
  276.         return;
  277.     }
  278.  
  279.     (*_FrBltVector)(GRF_BTOSCREEN, ctl->blitbuffer, &ctl->scrnrect);
  280.  
  281.     adjust = obj_clcalc(ctl->ptree, ROOT, NULL, NULL);
  282.     rc_gadjust(prect, adjust, adjust);
  283.  
  284.     oldmouse = graf_mouse(FLAT_HAND, NULL);
  285.     grfx_dragbox(prect, ctl->pboundrect, prect);
  286.     graf_mouse(oldmouse, NULL);
  287.  
  288.     adjust = -adjust;
  289.     rc_gadjust(prect, adjust, adjust);
  290.  
  291.     frm_sizes(ctl->ptree, &ctl->scrnrect);
  292.     (*_FrBltVector)(GRF_BFROMSCREEN, ctl->blitbuffer, &ctl->scrnrect);
  293.     frm_draw(ctl, ROOT);
  294. }
  295.  
  296. /*-------------------------------------------------------------------------
  297.  *
  298.  *-----------------------------------------------------------------------*/
  299.  
  300. short frm_do(ctl, editobj)
  301.     register FormControl *ctl;
  302.     short                   editobj;
  303. {
  304.     short oldmouse;
  305.     short more_interaction;
  306.     short rv;
  307.     short obj;
  308.     XUBT_STATUS status;
  309.  
  310.     if (ctl->options & FRM_MOUSEARROW) {
  311.         oldmouse = graf_mouse(ARROW, 0L);
  312.     }
  313.  
  314.     ctl->editobj = editobj;
  315.  
  316.     do    {
  317.         more_interaction = FALSE;
  318.         obj = 0x7FFF & (rv = (*ctl->form_do)(ctl));
  319.         if (rv == NO_OBJECT) {
  320.             goto QUICK_EXIT;
  321.         }
  322.         if (obj == ctl->moverobj) {
  323.             more_interaction = TRUE;
  324.             frm_move(ctl);
  325.         }
  326.         if (ctl->ptree[obj].ob_flags & TOUCHEXIT) {
  327.             if (ctl->ptree[obj].ob_state & DISABLED) {
  328.                 more_interaction = TRUE;
  329.             } else {
  330.                 if ((ctl->ptree[obj].ob_type & 0x00FF) == G_USERDEF) {
  331.                     more_interaction = TRUE;
  332.                     status = maybe_touch_object(ctl->ptree, rv);
  333.                     if (status & XUBT_DCEXIT) {
  334.                         if (NO_OBJECT != (rv = obj = obj_dxfind(ctl->ptree))) {
  335.                             more_interaction = FALSE;
  336.                         }
  337.                     }
  338.                 }
  339.             }
  340.         }
  341.     } while (more_interaction);
  342.  
  343.     if (ctl->ptree[obj].ob_flags & (EXIT|DEFAULT)) {
  344.         evnx_timer(70L);
  345.         obj_stchange(ctl->ptree, obj, ~ctl->select_state,
  346.             OBJ_CLIPDRAW, ctl->pboundrect);
  347.     }
  348.  
  349. QUICK_EXIT:
  350.  
  351.     if (ctl->options & FRM_MOUSEARROW) {
  352.         graf_mouse(oldmouse, 0L);
  353.     }
  354.  
  355.     return rv;
  356. }
  357.  
  358. /*-------------------------------------------------------------------------
  359.  *
  360.  *-----------------------------------------------------------------------*/
  361.  
  362. short frm_dialog(options, ptree, object)
  363.     long    options;
  364.     OBJECT *ptree;
  365.     short      object;
  366. {
  367.     FormControl ctl;
  368.     short          selobj;
  369.     long        actions;
  370.  
  371.     if (0 == (actions = options & FRM_ACTIONBITS)) {
  372.         options  |= (actions = FRM_DCOMPLETE);
  373.     }
  374.  
  375.     if (actions == FRM_DCOMPLETE) {
  376.         wind_update(BEG_UPDATE);
  377.     } else {
  378.         if (options & BLITOPTIONS) {
  379.             options &= ~BLITOPTIONS;
  380.         }
  381.     }
  382.  
  383.     _FrmSetup(&ctl, options, ptree, NULL);
  384.  
  385.     if (actions & FRM_DSTART) {
  386.         frm_start(&ctl);
  387.     }
  388.  
  389.     if (actions & FRM_DDRAW) {
  390.         frm_draw(&ctl, (options & FRM_DSTART) ? ROOT : object);
  391.     }
  392.  
  393.     if (actions & FRM_DDO) {
  394.         selobj = frm_do(&ctl, object);
  395.     }
  396.  
  397.     if (actions & FRM_DFINISH) {
  398.         frm_finish(&ctl);
  399.     }
  400.  
  401.     frm_cleanup(&ctl);
  402.  
  403.     if (actions == FRM_DCOMPLETE) {
  404.         wind_update(END_UPDATE);
  405.     }
  406.  
  407.     return selobj;
  408. }
  409.  
  410. /*-------------------------------------------------------------------------
  411.  *
  412.  *-----------------------------------------------------------------------*/
  413.  
  414. long frm_defaults(options)
  415.     long options;
  416. {
  417.     long rv = _FrmDefaults;
  418.  
  419.     if (options != FRM_GETDEFAULTS) {
  420.         _FrmDefaults = options & FRM_OPTIONBITS & ~FRM_NODEFAULTS;
  421.     }
  422.     return rv;
  423. }
  424.  
  425. /*-------------------------------------------------------------------------
  426.  *
  427.  *-----------------------------------------------------------------------*/
  428.  
  429. void *frm_dovector(newfunc)
  430.     void *newfunc;
  431. {
  432.     void *rv = default_form_do;
  433.  
  434.     if (newfunc != NULL) {
  435.         default_form_do = newfunc;
  436.     }
  437.     return rv;
  438. }
  439.  
  440.  
  441.  
  442.